package com.restaurant.application.minifacade;

import com.google.common.base.Strings;
import com.nebutown.base.data.View;
import com.nebutown.commonunits.utils.JacksonUtils;
import com.nebutown.generation.PickableBean;
import com.nebutown.generation.basictype.UID;
import com.restaurant.application.accumulategoods.AccumulateGoods;
import com.restaurant.application.accumulategoods.support.GoodsData;
import com.restaurant.application.coupon.Coupon;
import com.restaurant.application.customer.Customer;
import com.restaurant.application.customer.support.CustomerData;
import com.restaurant.application.indexes.accumulategoodslist.AccumulateShop;
import com.restaurant.application.indexes.accumulategoodslist.mysql.AccumulateGoodsListBean;
import com.restaurant.application.indexes.accumulategoodslist.mysql.AccumulateGoodsListCriteria;
import com.restaurant.application.indexes.accumulategoodslist.mysql.AccumulateGoodsListImpl;
import com.restaurant.application.indexes.bookingsetlist.AssistBookingSetList;
import com.restaurant.application.indexes.consumptionlist.AssistConsumptionList;
import com.restaurant.application.indexes.couponlist.AssistCouponList;
import com.restaurant.application.indexes.couponlist.mysql.CouponListBean;
import com.restaurant.application.indexes.couponlist.mysql.CouponListCriteria;
import com.restaurant.application.indexes.couponlist.mysql.CouponListImpl;
import com.restaurant.application.indexes.couponmanagelist.AssistCouponManageList;
import com.restaurant.application.indexes.customerlist.AssistCustomerList;
import com.restaurant.application.indexes.reservationlist.AssistReservationList;
import com.restaurant.application.indexes.reservationlist.mysql.ReservationListBean;
import com.restaurant.application.indexes.reservationlist.mysql.ReservationListCriteria;
import com.restaurant.application.indexes.reservationlist.mysql.ReservationListImpl;
import com.restaurant.application.minifacade.data.*;
import com.restaurant.application.reservation.Reservation;
import com.restaurant.application.reservation.support.ReservationData;
import com.restaurant.application.shoplist.ShopList;
import com.restaurant.application.signin.SignIn;
import com.restaurant.application.util.CommonUtils;
import com.restaurant.application.util.ResultBean;
import com.restaurant.application.util.wx.WXLogin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;
import java.util.Objects;

public class ActionController {

    private static final Logger LOG = LoggerFactory.getLogger(ActionController.class);

    private MiniFacadeImpl impl;
    private static final String VERIFY_CODE = "Verify_Code";

    public ActionController(MiniFacadeImpl impl) {
        this.impl = impl;
    }

    public View resultView(String message, PickableBean param) {
        ResultBean<PickableBean> resultBean = new ResultBean<>();
        resultBean.setMessage(message);
        resultBean.setData(param);
        return impl.dataOnly(impl.getClass().getName(), resultBean);
    }

    public View doRegister(String json) {
        IdBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, IdBO.class);
        } catch (Exception e) {
            LOG.error("doRegister", e);
        }
        if (bean == null) {
            return resultView("error", null);
        }
        if (Strings.isNullOrEmpty(bean.getId())) {
            return resultView("error", new MainBO());
        }
        Map<String, String> stringObjectMap = WXLogin.code2Session(bean.getId());
        String openid = stringObjectMap.get("openid");
        UID uid = impl.getSingleton(AssistCustomerList.class).getCustomerUidByOpenId(openid);
        if (uid != null) {
            impl.setGate(uid);
            return resultView("success", impl.getUnit(Customer.class, uid).getMainBO());
        }
        return resultView("error", null);
    }

    public View doVerify(String json) {
        PhoneBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, PhoneBO.class);
        } catch (Exception e) {
            LOG.error("doVerify", e);
        }
        if (bean == null || Strings.isNullOrEmpty(bean.getPhone())) {
            return resultView("error", null);
        }
        CommonUtils.sendPhoneCode(impl, bean.getPhone(), VERIFY_CODE);
        return resultView("success", null);
    }

    public View doMainPageInfo(String json) {
        UID gate = impl.getGate();
        if (gate != null) {
            return resultView("success", impl.getUnit(Customer.class, gate).getMainBO());
        }
        return resultView("error", null);
    }

    public View doLogin(String json) {
        RegisterBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, RegisterBO.class);
        } catch (Exception e) {
            LOG.error("doLogin", e);
        }
        if (bean == null) {
            return resultView("error", null);
        }
        if (!Objects.equals(impl.getFromSessionCache(VERIFY_CODE), bean.getVerifyCode())) {
            return resultView("验证码不正确！", null);
        }
        Map<String, String> stringObjectMap = WXLogin.code2Session(bean.getWxCode());
        String openid = stringObjectMap.get("openid");
        UID uid = impl.getSingleton(AssistCustomerList.class).getCustomerUidByOpenId(openid);
        if (uid != null) {
            impl.setGate(uid);
        } else {
            String message = impl.createNode(Customer.class).init(
                    new CustomerData().withOpenId(openid).withAvatarUrl(bean.getAvatarUrl()).withPhone(bean.getPhone())
                            .withNickName(bean.getNickName()).withGender(getGender(bean.getGender())));
            return resultView(message, new MainBO().withNickName(bean.getNickName()));
        }
        return resultView("success", new MainBO().withNickName(bean.getNickName()));
    }

    private String getGender(Integer num) {
        String result = "";
        if (Objects.isNull(num)) {
            num = 0;
        }
        switch (num) {
            case 1:
                result = "男";
                break;
            case 2:
                result = "女";
                break;
            default:
        }
        return result;
    }

    public View doGetInformation(String json) {
        PersonBO bo = impl.getUnit(Customer.class, impl.getGate()).getPersonBO();
        return resultView("success", bo);
    }

    public View doInformationCommit(String json) {
        PersonBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, PersonBO.class);
        } catch (Exception e) {
            LOG.error("doInformationCommit", e);
        }
        if (bean == null) {
            LOG.error("doInformationCommit error");
            return resultView("error", null);
        }
        String message = impl.getUnit(Customer.class, impl.getGate()).update(new CustomerData().withNickName(bean.getNickName())
                .withGender(bean.getGender()).withPhone(bean.getPhone()).withBirthday(bean.getBirthday()));
        return resultView(message, null);
    }

    public View doGetSignIn(String json) {
        SignInBO bo = impl.createNode(SignIn.class).init();
        return resultView(bo.getMessage(), bo);
    }

    public View doGetShopNameList(String json) {
        BookingBO shops = impl.getSingleton(AssistBookingSetList.class).findBookingShops();
        return resultView("success", shops);
    }

    public View doMyReservationCommit(String json) {
        ReservationPageBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, ReservationPageBO.class);
        } catch (Exception e) {
            LOG.error("doMyReservationCommit", e);
        }
        if (bean == null) {
            LOG.error("doMyReservationCommit error");
            return resultView("error", null);
        }
        ReservationData data = new ReservationData().withShopName(bean.getShopName())
                .withPersonAmount(bean.getCount()).withDate(CommonUtils.dateTimeToLong(bean.getShopDate())).withTime(bean.getShopTime()).withRemarks(bean.getRemark())
                .withShopUid(impl.getSingleton(ShopList.class).findShopByName(bean.getShopName())).withServiceName(bean.getService());
        String s = impl.createNode(Reservation.class).init(data);
        return resultView(s, null);
    }

    public View doGetMyReservationList(String json) {
        List<ReservationPageBO> bean = impl.getSingleton(AssistReservationList.class).getReservationBean(impl.getGate());
        return resultView("success", new ReservationListBO().withLists(bean));
    }

    public View doGetMyReservationDetail(String json) {
        IdBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, IdBO.class);
        } catch (Exception e) {
            LOG.error("doGetMyReservationDetail", e);
        }
        if (bean == null) {
            LOG.error("doGetMyReservationDetail error");
            return resultView("error", null);
        }
        List<ReservationListBean> search = impl.getIndex(ReservationListImpl.class).search(new ReservationListCriteria().withNumberEquals(bean.getId()), null, 2);
        if (search.size() == 0) {
            return resultView("订单号不正确！", null);
        }
        ReservationPageBO bo = impl.getUnit(Reservation.class, search.get(0).getReservationUid()).getReservationBean();
        return resultView("success", bo);
    }

    public View doCancelReservation(String json) {
        IdBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, IdBO.class);
        } catch (Exception e) {
            LOG.error("doCancelReservation", e);
        }
        if (bean == null) {
            LOG.error("doCancelReservation error");
            return resultView("error", null);
        }
        List<ReservationListBean> search = impl.getIndex(ReservationListImpl.class).search(new ReservationListCriteria().withNumberEquals(bean.getId()), null, 2);
        if (search.size() == 0) {
            LOG.error("doCancelReservation error not find reservationNumber");
            return resultView("订单号不正确！", null);
        }
        String s = impl.getUnit(Reservation.class, search.get(0).getReservationUid()).cancel();
        return resultView(s, null);
    }

    public View doGetConsumeHistory(String json) {
        ConsumptionListBO bo = impl.getSingleton(AssistConsumptionList.class).getHistory();
        return resultView("success", bo);
    }

    public View doGetCardList(String json) {
        List<CardBO> list = impl.getSingleton(AssistCouponManageList.class).getAllNormal();
        return resultView("success", new CardListBO().withLists(list));
    }

    public View doGetMyCardList(String json) {
        List<CardBO> list = impl.getSingleton(AssistCouponList.class).getMyCardBeanList(impl.getGate(), null, null);
        return resultView("success", new CardListBO().withLists(list));
    }

    public View doGetMyCardListByStatus(String json) {
        StatusBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, StatusBO.class);
        } catch (Exception e) {
            LOG.error("doGetMyReservationDetail", e);
        }
        if (bean == null) {
            LOG.error("doGetMyReservationDetail error");
            return resultView("error", null);
        }
        List<CardBO> list = impl.getSingleton(AssistCouponList.class).getMyCardBeanList(impl.getGate(), bean.getStatus(), null);
        return resultView("success", new CardListBO().withLists(list));
    }

    public View doGetCardDetail(String json) {
        IdBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, IdBO.class);
        } catch (Exception e) {
            LOG.error("doGetCardDetail", e);
        }
        if (bean == null) {
            LOG.error("doGetCardDetail error");
            return resultView("error", null);
        }
        List<CouponListBean> search = impl.getIndex(CouponListImpl.class).search(new CouponListCriteria().withNumberEquals(bean.getId()), null, 2);
        if (search.size() == 0) {
            LOG.error("doGetCardDetail error not find cardNumber");
            return resultView("优惠券号不正确！", null);
        }
        CardBO cardBean = impl.getUnit(Coupon.class, search.get(0).getCouponUid()).getCardBean();
        return resultView("success", cardBean);
    }

    public View doGetGoodsList(String json) {
        GoodsPageBO bo = impl.getSingleton(AccumulateShop.class).getMiniPage();
        return resultView("success", bo);
    }

    public View doGetGoodsDetail(String json) {
        IdBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, IdBO.class);
        } catch (Exception e) {
            LOG.error("doGetGoodsDetail", e);
        }
        if (bean == null) {
            LOG.error("doGetGoodsDetail error");
            return resultView("error", null);
        }
        List<AccumulateGoodsListBean> search = impl.getIndex(AccumulateGoodsListImpl.class).search(new AccumulateGoodsListCriteria().withGoodsIdEquals(bean.getId()), null, 2);
        if (search.size() == 0) {
            LOG.error("doGetGoodsDetail error not find goodsNumber");
            return resultView("商品没找到！", null);
        }
        GoodsData data = impl.getUnit(AccumulateGoods.class, search.get(0).getGoodsUID()).getGoodsData();
        return null;
    }

    public View doQuickChange(String json) {
        IdBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, IdBO.class);
        } catch (Exception e) {
            LOG.error("doQuickChange", e);
        }
        if (bean == null) {
            LOG.error("doQuickChange error");
            return resultView("error", null);
        }
        ResultBean bo = impl.getSingleton(AccumulateShop.class).exchangeGoods(bean);
        return resultView(bo.getMessage(), bo);
    }

    public View doSearchGoods(String json) {
        SearchGoodsBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, SearchGoodsBO.class);
        } catch (Exception e) {
            LOG.error("doSearchGoods", e);
        }
        if (bean == null) {
            LOG.error("doSearchGoods error");
            return resultView("error", null);
        }
        GoodsPageBO bo = impl.getSingleton(AccumulateShop.class).miniSearchGoods(bean);
        return resultView("success", bo);
    }

    public View doGetShopAddress(String json) {
        List<ShopBO> bo = impl.getSingleton(ShopList.class).findAllShopBO();
        return resultView("success", new ShopListBO().withLists(bo));
    }

    public View doChangePhone(String json) {
        PhoneBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, PhoneBO.class);
        } catch (Exception e) {
            LOG.error("doChangePhone", e);
        }
        if (bean == null) {
            LOG.error("doChangePhone error");
            return resultView("error", null);
        }
        if (!Objects.equals(impl.getFromSessionCache(VERIFY_CODE), bean.getCode())) {
            return resultView("验证码不正确！", null);
        }
        String s = impl.getUnit(Customer.class, impl.getGate()).update(new CustomerData().withPhone(bean.getPhone()));
        return resultView(s, null);
    }

    public View doGetBookingDate(String json) {
        BookingPageBO bean = null;
        try {
            bean = JacksonUtils.json2pojo(json, BookingPageBO.class);
        } catch (Exception e) {
            LOG.error("doGetBookingDate", e);
        }
        if (bean == null) {
            LOG.error("doGetBookingDate error");
            return resultView("error", null);
        }
        if (Strings.isNullOrEmpty(bean.getShopId())) {
            List<ShopBookingTime> bs = impl.getSingleton(AssistBookingSetList.class).findBookingSetListByService(bean.getService());
            return resultView("success", new ReservationBO().withLists(bs));
        }
        ShopBookingTime bo = impl.getSingleton(AssistBookingSetList.class).findBookingSetList(bean.getShopId(), bean.getService());
        return resultView("success", bo);
    }

}
